<!DOCTYPE html>
<html>
<head>
    <title>Energy Level Diagram</title>
    <style>
        body {
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            margin: 0;
            background-color: #f0f0f0;
        }
        canvas {
            border: 1px solid #ccc;
            background-color: #fff;
        }
    </style>
</head>
<body>
<canvas id="physicsCanvas" width="450" height="400"></canvas>
<script>
    const canvas = document.getElementById('physicsCanvas');
    const ctx = canvas.getContext('2d');

    // --- Style Settings ---
    ctx.strokeStyle = 'black';
    ctx.fillStyle = 'black';
    ctx.lineWidth = 2.5;
    ctx.font = "bold 20px 'Georgia', serif";
    ctx.textAlign = 'left';
    ctx.textBaseline = 'middle';

    // --- Helper Functions ---

    /**
     * Draws a straight arrow from (fromx, fromy) to (tox, toy).
     * @param {CanvasRenderingContext2D} ctx - The canvas rendering context.
     * @param {number} fromx - The starting x-coordinate.
     * @param {number} fromy - The starting y-coordinate.
     * @param {number} tox - The ending x-coordinate.
     * @param {number} toy - The ending y-coordinate.
     */
    function drawArrow(ctx, fromx, fromy, tox, toy) {
        const headlen = 10;
        const dx = tox - fromx;
        const dy = toy - fromy;
        const angle = Math.atan2(dy, dx);

        // Main line of the arrow
        ctx.beginPath();
        ctx.moveTo(fromx, fromy);
        ctx.lineTo(tox, toy);
        ctx.stroke();

        // Arrowhead
        ctx.beginPath();
        ctx.moveTo(tox, toy);
        ctx.lineTo(tox - headlen * Math.cos(angle - Math.PI / 6), toy - headlen * Math.sin(angle - Math.PI / 6));
        ctx.moveTo(tox, toy);
        ctx.lineTo(tox - headlen * Math.cos(angle + Math.PI / 6), toy - headlen * Math.sin(angle + Math.PI / 6));
        ctx.stroke();
    }

    /**
     * Draws a wavy (zig-zag) arrow.
     * @param {CanvasRenderingContext2D} ctx - The canvas rendering context.
     * @param {number} x1 - The starting x-coordinate.
     * @param {number} y1 - The starting y-coordinate.
     * @param {number} x2 - The ending x-coordinate.
     * @param {number} y2 - The ending y-coordinate.
     * @param {number} zigs - The number of zigs/zags in the wave.
     * @param {number} height - The amplitude of the wave.
     */
    function drawWavyArrow(ctx, x1, y1, x2, y2, zigs, height) {
        const dx = x2 - x1;
        const dy = y2 - y1;
        const length = Math.sqrt(dx * dx + dy * dy);
        const angle = Math.atan2(dy, dx);
        const headlen = 10;

        ctx.save();
        ctx.translate(x1, y1);
        ctx.rotate(angle);

        // Wavy line part
        ctx.beginPath();
        ctx.moveTo(0, 0);
        // We subtract headlen from the total length to prevent the wave from overlapping the arrowhead
        const waveLength = length - headlen;
        for (let i = 0; i < zigs; i++) {
            const x = (i + 0.5) * waveLength / zigs;
            const y = height * (i % 2 === 0 ? 1 : -1);
            ctx.lineTo(x, y);
        }
        ctx.lineTo(length, 0);
        ctx.stroke();

        // Arrowhead (aligned with the main axis of the arrow)
        ctx.beginPath();
        ctx.moveTo(length, 0);
        ctx.lineTo(length - headlen, -5);
        ctx.moveTo(length, 0);
        ctx.lineTo(length - headlen, 5);
        ctx.stroke();

        ctx.restore();
    }

    // --- Main Drawing ---

    // Energy Level E1 (ground state)
    ctx.beginPath();
    ctx.moveTo(50, 320);
    ctx.lineTo(400, 320);
    ctx.stroke();
    ctx.fillText("E₁", 410, 320);

    // Energy Level E2 (metastable state)
    ctx.beginPath();
    ctx.moveTo(240, 200);
    ctx.lineTo(400, 200);
    ctx.stroke();
    ctx.fillText("E₂", 410, 200);

    // Energy Level E3 (pump band)
    ctx.beginPath();
    ctx.rect(50, 80, 250, 40);
    ctx.stroke();
    ctx.fillText("E₃", 320, 80);

    // Pumping transition (E1 -> E3)
    drawArrow(ctx, 100, 320, 100, 120);

    // Non-radiative decay (E3 -> E2)
    drawWavyArrow(ctx, 210, 125, 230, 195, 4, 6);

    // Lasing transition (E2 -> E1)
    drawArrow(ctx, 280, 200, 280, 320);

    // Emitted photon (hν)
    drawWavyArrow(ctx, 300, 270, 350, 280, 4, 5);
    ctx.fillText("hν", 290, 250);

    // Figure caption
    ctx.textAlign = 'center';
    ctx.fillText("Fig. 3.1", 225, 370);

</script>
</body>
</html>